Dart _fe_analyzer_shared parser Parser
用于解析 Dart 程序的事件生成解析器。这个解析器预期所有的令牌都在一个链表(即令牌流,Token)中,由类 Scanner 生成一个令牌流。
该类会抛出事件,由 Listener 类的子类用于监听事件。
这个类的大多数方法属于四个主要类别之一:
- 解析方法:parse methods
- 窥视方法:peek methods
- 确保方法:ensure methods
- 跳过方法:skip methods
解析方法:
解析方法都有前缀 parse
,通过调用 listener 上的方法来生成事件,并返回下一个要解析的令牌。一些例外,如 parseFunctionBody 和 parseClassOrMixinOrExtensionBody 等方法返回的是最后一个解析的令牌,而不是下一个要解析的令牌。解析方法通常命名为 parseGrammarProductionSuffix
。后缀可以是 opt
或 star
。opt
表示零个或一个匹配,star
表示零个或多个匹配。例如,parseMetadataStar 对应于语法片段:metadata*
,而 parseArgumentsOpt 对应于:arguments?
。
窥视方法都有前缀 peek
,不生成事件(除了错误),并且可能返回 null。
确保方法都有前缀 ensure
并且可能会生成事件。如果当前令牌不匹配,它们会返回当前令牌,或插入并返回一个合成令牌。例如,ensureSemicolon 会在当前令牌是分号的情况下返回当前令牌,否则在当前令牌之前插入一个合成分号到令牌流中,然后返回那个新的合成令牌。
跳过方法类似于解析方法,但都有 skip
前缀,并跳过被解析文件的某些部分。通常,跳过方法会为被跳过的结构生成一个事件,但不为其子结构生成。
当前令牌
当前令牌始终可以在名为 token
的正式参数中找到。这个参数应该是第一个,因为这增加了编译器将其放在寄存器中的机会。
实现说明
解析器假定关键字、内置标识符和其他特殊单词(伪关键字)都是规范化的。要扩展解析器以识别新的标识符,应该修改 keyword.dart 并确保标识符被添加到关键字表中。
因此,不应该在解析器中使用 == 来比较字符串。应该更倾向于使用方法 optional 和 expect 来识别关键字或标识符。在某些情况下,可以使用 identical 来比较令牌的 stringValue,但通常 optional 就足够了。
从历史上看,我们过度使用了 identical,而当在非字符串对象上使用 identical 时,通常可以被 == 替代。
灵活性、可扩展性和规范性
解析器旨在灵活和可扩展。它的方法被设计为可以在子类中被覆盖,因此可以扩展来处理未规定的语言扩展或实验,同时这个文件中的所有内容都尝试遵循规范(除非它干扰到错误恢复)。
我们通过遵循几个经验法则来实现灵活性、可扩展性和规范性:
-
解析器中的所有方法应该是公开的。
-
方法遵循指定的语法,并不实现自定义扩展,例如
native
。 -
解析器不重写令牌流(处理
>>
除外)。
解析器不生成抽象语法树(AST),这是 [Listener] 的职责。
解析器不应该过度假设 [Listener] 的行为。
Parser 中的 listener
Listener 是 Parser 中的一个类属性,扮演了很重要的作用。该属性由外部通过构造函数传入。
parseUnit
parseUnit
是 Parser
类中的一个方法,它的主要任务是解析一个编译单元。在 Dart 中,一个编译单元通常对应一个源文件。
主要步骤:
-
首先,它跳过并记录所有的错误令牌,以便在最后报告。
-
然后,它调用
listener.beginCompilationUnit
方法来通知监听器开始解析一个新的编译单元。 -
接下来,它创建一个
DirectiveContext
对象,用于跟踪解析过程中的指令状态。 -
然后,它检查下一个令牌是否是脚本标签(
#!
)。如果是,它会解析这个脚本标签。 -
接下来,它进入一个循环,不断解析顶级声明,直到遇到文件结束(EOF)令牌。
-
在每次解析完一个顶级声明后,它都会调用
listener.endTopLevelDeclaration
方法来通知监听器结束解析一个顶级声明。 -
如果在解析过程中没有进展(即当前令牌和下一个令牌相同),那么它会报告一个可恢复的错误,并跳过当前令牌。
-
在解析完所有的顶级声明后,它会调用
listener.endCompilationUnit
方法来通知监听器结束解析这个编译单元。 -
最后,它会报告所有之前跳过的错误令牌,并清除可能导致内存泄漏的字段。
这个方法的主要作用是解析一个编译单元,这是编译器前端的一个重要步骤。
本文作者:Maeiee
本文链接:Dart _fe_analyzer_shared parser Parser
版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!
喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!